package com.pulse.common.utils.sor;

import com.pulse.common.utils.sor.domain.*;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class KeyEvents {
    /**
     * 处理 KeyEvents 块
     *
     * @param fh      输入流
     * @param sorInfo 存储结果的对象
     * @return 状态字符串
     */
    public static String process(BufferedInputStream fh, SorInfo sorInfo) {
        final String bname = "KeyEvents";
        int hsize = bname.length() + 1; // 包括尾部的 '\0'
        final String pname = bname + ".process():";
        Block refBlock = null;
        String status = "nok";

        try {
            // 获取块的引用
            refBlock = sorInfo.getBlocks().getKeyEvents();
            long startpos = (long) refBlock.getPos();
            fh.reset();
            fh.skip(startpos);  // 跳过块的起始位置
        } catch (Exception ex) {
            return status;
        }

        int format = (int) sorInfo.getFormat();

        if (format == 2) {
            // 读取并验证头部
            byte[] buffer = new byte[hsize];
            try {
                fh.read(buffer, 0, hsize);
            } catch (IOException e) {
                return status;
            }
            String mystr = new String(buffer, StandardCharsets.US_ASCII);
            if (!mystr.equals(bname + "\0")) {
                return status;
            }
        }

        // 初始化 KeyEvents 字典
        sorInfo.setKeyEvents(new KeyEventsVo());

        // 处理事件
        try {
            status = processKeyEvents(fh, format, sorInfo);
        } catch (IOException e) {
            return status;
        }

        // 读取块的剩余部分（如果需要）
        long endpos = (long) sorInfo.getBlocks().getKeyEvents().getPos()
                + (long) sorInfo.getBlocks().getKeyEvents().getSize();

        try {
            fh.skip(endpos - fh.available());
        } catch (IOException e) {
            return status;
        }

        status = "ok";
        return status;
    }

    /**
     * 处理 KeyEvents 数据
     */
    private static String processKeyEvents(BufferedInputStream fh, int format, SorInfo sorInfo) throws IOException {
        final String bname = "KeyEvents";
        KeyEventsVo xref = sorInfo.getKeyEvents();

        // 读取事件数量
        int nev = (int) Parts.getUInt(fh, 2);

        xref.setNumEvents(nev);

        double factor = 1e-4 * Parts.Sol / Double.parseDouble (sorInfo.getFxdParams().getIndex());

        Pattern pat = Pattern.compile("(.)(.)9999LS");

        xref.setEvents(new ArrayList<>());
        for (int j = 0; j < nev; j++) {
            EventVo x2ref = new EventVo();
            x2ref.setEventNum(j+1);
            xref.getEvents().add(x2ref);

            int xid = (int) Parts.getUInt(fh, 2); // 事件编号
            double dist = Parts.getUInt(fh, 4) * factor; // 距离

            double slope = Parts.getSigned(fh, 2) * 0.001; // 斜率（事件段平均衰耗）
            double splice = Parts.getSigned(fh, 2) * 0.001; // 接头损耗（插入损耗）
            double refl = Parts.getSigned(fh, 4) * 0.001; // 反射损耗（回波损耗）

            byte[] xtypeBytes = new byte[8];
            fh.read(xtypeBytes, 0, 8);
            String xtype = new String(xtypeBytes, StandardCharsets.US_ASCII).trim();

            Matcher mresults = pat.matcher(xtype);
            if (mresults.matches()) {
                String subtype = mresults.group(1);
                String manual = mresults.group(2);

                if (manual.equals("A")) {
                    xtype += " {manual}";
                } else {
                    xtype += " {auto}";
                }

                if (subtype.equals("1")) {
                    xtype += " reflection";
                } else if (subtype.equals("0")) {
                    xtype += " loss/drop/gain";
                } else if (subtype.equals("2")) {
                    xtype += " multiple";
                } else {
                    xtype += " unknown '" + subtype + "'";
                }
            } else {
                xtype += " [unknown type " + xtype + "]";
            }

            if (format == 2) {
                double endPrev = Parts.getUInt(fh, 4) * factor; // 上一个事件的结束位置
                double startCurr = Parts.getUInt(fh, 4) * factor; // 当前事件的开始位置
                double endCurr = Parts.getUInt(fh, 4) * factor; // 当前事件的结束位置
                double startNext = Parts.getUInt(fh, 4) * factor; // 下一个事件的开始位置
                double pkpos = Parts.getUInt(fh, 4) * factor; // 事件的峰值位置

                x2ref.setEndOfPrev(String.format("%.3f", endPrev));
                x2ref.setStartOfCurr(String.format("%.3f", startCurr));
                x2ref.setEndOfCurr(String.format("%.3f", endCurr));
                x2ref.setStartOfNext(String.format("%.3f", startNext));
                x2ref.setPeak(String.format("%.3f", pkpos));
            }

            String comments = Parts.getString(fh);

            x2ref.setType(xtype);
            x2ref.setDistance(String.format("%.3f", dist));
            x2ref.setSlope(String.format("%.3f", slope));
            x2ref.setSpliceLoss(String.format("%.3f", splice));
            x2ref.setReflLoss(String.format("%.3f", refl));
            x2ref.setComments(comments);
        }

        // 读取总结信息
        double total = Parts.getSigned(fh, 4) * 0.001; // 总损耗
        double lossStart = Parts.getSigned(fh, 4) * factor; // 损耗起始位置
        double lossFinish = Parts.getUInt(fh, 4) * factor; // 损耗结束位置
        double orl = Parts.getUInt(fh, 2) * 0.001; // 光回波损耗 (ORL)
        double orlStart = Parts.getSigned(fh, 4) * factor; // ORL 起始位置
        double orlFinish = Parts.getUInt(fh, 4) * factor; // ORL 结束位置

        Summary x3ref = new Summary();
        x3ref.setTotalLoss(total);
        x3ref.setOrl(orl);
        x3ref.setLossStart(lossStart);
        x3ref.setLossEnd(lossFinish);
        x3ref.setOrlStart(orlStart);
        x3ref.setOrlFinish(orlFinish);
        xref.setSummary(x3ref);

        return "ok";
    }
}
